package g7xx

/*
#include "g726.h"

void* cgo_g726_init(int bit_rate, int ext_coding, int packing) {
	return (void*)g726_init(NULL, bit_rate, ext_coding, packing);
}

int cgo_g726_decode(void *ptr, char* amp, char* g726_data, int g726_bytes) {
	int amplen = g726_decode((g726_state_t*)ptr, (int16_t*)amp, (const uint8_t*)g726_data, g726_bytes);
	return amplen * sizeof(int16_t);
}

int cgo_g726_encode(void *ptr, char* g726_data, char* amp, int sample) {
	int g726_bytes = g726_encode((g726_state_t*)ptr, (uint8_t*)g726_data, (int16_t*)amp, sample / (sizeof(int16_t)));
	return g726_bytes * sizeof(int16_t);
}

void cgo_g726_release(void *ptr) {
	g726_release((g726_state_t*)ptr);
}
*/
import "C"

import "unsafe"

const (
	ENCODING_LINEAR = iota
	ENCODING_ULAW
	ENCODING_ALAW
)

const (
	PACKING_NONE = iota
	PACKING_LEFT
	PACKING_RIGHT
)

type G726 struct {
	ptr  unsafe.Pointer //
	dest []byte         //
}

func cInt(s int) C.int {
	return C.int(s)
}

func cCharPtr(s []byte) *C.char {
	return (*C.char)(unsafe.Pointer(&s[0]))
}

func Init(bitRate, extCoding, packing int) *G726 {
	var g G726
	g.ptr = C.cgo_g726_init(cInt(bitRate), cInt(extCoding), cInt(packing))
	g.dest = make([]byte, 1024)
	return &g
}

func (g *G726) Decode(s []byte) []byte {
	l := C.cgo_g726_decode(g.ptr, cCharPtr(g.dest), cCharPtr(s), cInt(len(s)))
	return g.dest[:l]
}

func (g *G726) Encode(s []byte) []byte {
	l := C.cgo_g726_encode(g.ptr, cCharPtr(s), cCharPtr(g.dest), cInt(len(s)))
	return g.dest[:l]
}

func (g *G726) EncodeHisi(s []byte) []byte {
	g.dest = append(g.dest, 0x00)
	g.dest = append(g.dest, 0x01)
	l := C.cgo_g726_encode(g.ptr, cCharPtr(s), cCharPtr(g.dest[4:]), cInt(len(s)))
	g.dest = append(g.dest, byte(l/2))
	g.dest = append(g.dest, 0x00)
	return g.dest[:l+4]
}

func (g *G726) Release() {
	C.cgo_g726_release(g.ptr)
}
